package com.guo.anim.group;

import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.RadioButton;
import android.widget.RadioGroup;

import com.guo.anim.R;

import java.util.ArrayList;
import java.util.List;

/**
 * 自定义联动滑动动效的RadioGroup
 *
 * @author dfzhangling
 * @date 2022/06/09
 */
public class CustomRadioGroup extends RadioGroup implements CompoundButton.OnCheckedChangeListener {
    private static final String TAG = "CustomRadioGroup";
    private static final int ANIM_TIMER = 300;/*动画持续时间*/
    private int mIndex = 0;
    private Bitmap bitmap;/*滑动动画的图片*/
    private int width;/*单个radioButton的宽度*/
    private int height;/*单个radioButton的高度*/
    private final Context mContext;
    private List<String> mList = new ArrayList<>();/*用户输入的radioButton的文本，也要靠它决定radioButton的数目*/
    private float mCanvasX = 0;/*滑动动画的控制参数*/
    private float textSizeOfRadioButton;/*RadioButton的textSize*/
    private int drawId;/*滑动动画的图片ID*/
    private int textColorChecked;/*RadioButton的选中态的text颜色*/
    private int textColorUnChecked;/*RadioButton的选中态的text颜色*/
    private int backgroundId;/*RadioGroup的背景图片*/
    private CheckedCallBack mCheckedCallBack;/*radioButton的点击回调*/
    private int mOrientation;

    public CustomRadioGroup(Context context) {
        super(context);
        this.mContext = context;
    }

    public CustomRadioGroup(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.mContext = context;
//       自定义属性参数
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomRadioGroup);
        textSizeOfRadioButton = typedArray.getDimension(R.styleable.CustomRadioGroup_radio_button_text_size, 28);/*自定义RadioButton的textSize*/
        Log.d(TAG, "textSizeOfRadioButton:" + textSizeOfRadioButton);
        drawId = typedArray.getResourceId(R.styleable.CustomRadioGroup_drawable_radio_button_checked, R.drawable.shape_button_selected);/*自定义滑动动画的图片*/
        Log.d(TAG, "drawId: " + drawId);
        textColorChecked = typedArray.getColor(R.styleable.CustomRadioGroup_radio_button_text_color_checked, getResources().getColor(R.color.black));/*自定义RadioButton的选中态的text颜色*/
        Log.d(TAG, "textColorChecked: " + textColorChecked);
        textColorUnChecked = typedArray.getColor(R.styleable.CustomRadioGroup_radio_button_text_color_unchecked, getResources().getColor(R.color.white));/*自定义RadioButton的未选中态的text颜色*/
        Log.d(TAG, "textColorUnChecked:" + textColorUnChecked);
        backgroundId = typedArray.getResourceId(R.styleable.CustomRadioGroup_android_background, R.drawable.shape_group_bgd);/*自定义RadioGroup的背景图片*/
        typedArray.recycle();
//        设置默认的初始文本，可以被用户覆盖掉
        mList.add("南门");
        mList.add("北门");
        mList.add("东门");
        mList.add("西门");
        init();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//        获取单个RadioButton的宽高
        if (width == 0 || height == 0) {
            width = getChildAt(0).getMeasuredWidth();
            height = getChildAt(0).getMeasuredHeight();
        }
        Log.d(TAG, "width: " + width);
        Log.d(TAG, "height: " + height);
        bitmap = BitmapFactory.decodeResource(getResources(), drawId);
        /*设置滑动动画的图片*/
        if (bitmap.getWidth() != width || bitmap.getHeight() != height) {
            bitmap = Bitmap.createScaledBitmap(bitmap, width, height, false);/*调整bitmap尺寸与RadioButton相同*/
        }
    }

    private void init() {
        addRadioButton();
//        bitmap = BitmapFactory.decodeResource(getResources(), drawId);
        setBackgroundResource(backgroundId);/*设置RadioGroup的背景图片*/
        mOrientation=getOrientation();
    }

    /**
     * 动态添加RadioButton
     */
    private void addRadioButton() {
        removeAllViews();/*删除默认添加的RadioButton*/
        Log.d(TAG, "init:" + mList.size());
        for (int i = 0; i < mList.size(); i++) {
            setRadioButton(i);
            Log.d(TAG, "init: RadioButton" + i);
        }
    }

    /**
     * 设置RadioButton参数
     *
     * @param id RadioButton的id
     */
    private void setRadioButton(int id) {
        RadioButton mRadioButton = new RadioButton(mContext);
        mRadioButton.setId(id);
        mRadioButton.setText(mList.get(id));
        mRadioButton.setTextSize(textSizeOfRadioButton);
//        todo 设置padding，留空隙
        if (mOrientation==HORIZONTAL) {
            mRadioButton.setLayoutParams(new LayoutParams(0, LayoutParams.MATCH_PARENT, 1f));/*设置RadioButton宽度的权重平分*/
        } else {
            mRadioButton.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, 0, 1f));
            mRadioButton.setEms(1);
        }

        mRadioButton.setGravity(Gravity.CENTER);/*设置文本居中*/
        addView(mRadioButton);
        mRadioButton.setOnCheckedChangeListener(this);
        mRadioButton.setButtonDrawable(android.R.color.transparent);/*隐藏RadioButton的选中状态图标*/
        if (!mRadioButton.isChecked()) {
            mRadioButton.setTextColor(textColorUnChecked);/*设置未选中态的文本颜色*/
        }
    }


    /**
     * 设置点击时滑动动画
     *
     * @param id RadioButton的id
     */
    private void setCheckedAnimation(int id) {
        int destIndex = indexOfChild(findViewById(id));
        setAnimation(mIndex, destIndex);/*通过点击前后button的Id参数设置滑动动画*/
        mIndex = destIndex;
    }

    /**
     * 重写RadioButton选中状态变更的回调方法
     *
     * @param buttonView 变更的button
     * @param isChecked  选中状态
     */
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        if (isChecked) {
            setCheckedAnimation(buttonView.getId());
            buttonView.setTextColor(textColorChecked);/*设置选中态的文本颜色*/
            Log.d(TAG, "onCheckedChanged: Checked" + buttonView.getId());
//            选中后的回调
            if (mCheckedCallBack != null) {
                mCheckedCallBack.radioButtonChecked(buttonView.getId(), mList.get(buttonView.getId()));
                Log.d(TAG, "mCheckedCallBack.RadioButtonChecked: " + buttonView.getId() + ":" + mList.get(buttonView.getId()));
            }
        }
        if (!isChecked) {
            Log.d(TAG, "onCheckedChanged: Not Checked" + buttonView.getId());
            buttonView.setTextColor(textColorUnChecked);/*设置未选中态的文本颜色*/
        }
    }

    /**
     * 设置button滑动动画
     *
     * @param originId 起始坐标
     * @param finalId  终点坐标
     */
    private void setAnimation(int originId, int finalId) {
        ValueAnimator valueAnimator = ValueAnimator.ofFloat(originId, finalId);/*设置位移变化动画*/
        valueAnimator.addUpdateListener(animation -> {
            mCanvasX = (float) animation.getAnimatedValue();/*同步滑块位置参数*/
            postInvalidate();/*同步OnDraw，重新绘制滑块*/
        });
        valueAnimator.setDuration(ANIM_TIMER);/*动画持续时间*/
        valueAnimator.start();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Log.d(TAG, "onDraw: ");
        if (mOrientation==HORIZONTAL) {
            canvas.drawBitmap(bitmap, mCanvasX * width, 0, null);/*绘制滑块的图片*/
        } else {
            canvas.drawBitmap(bitmap, 0, mCanvasX * height, null);/*绘制滑块的图片*/
        }
    }

    /**
     * 设置RadioButton文本内容(外抛使用）
     *
     * @param List 文本list
     */
    public void setTextList(List<String> List) {
        mList.clear();
        mList = List;
        addRadioButton();
    }

    /**
     * 单选RadioButton方法（外抛使用）
     *
     * @param id
     */
    public void setRadioButtonChecked(int id) {
        RadioButton mRadioButton = (RadioButton) getChildAt(id);
        if (!mRadioButton.isChecked()) {
            mRadioButton.setChecked(true);
        }
    }

    /**
     * 设置RadioButton单选回调
     *
     * @param checkedCallBack 回调接口
     */
    public void setCheckedCallBack(CheckedCallBack checkedCallBack) {
        this.mCheckedCallBack = checkedCallBack;
    }

    /**
     * RadioButton单选后的回调
     */
    public interface CheckedCallBack {
        void radioButtonChecked(int position, String name);
    }
}
